package com.linktco.common.utils;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 模板占位符替换工具
 * @author zhangnx
 */
public class TemplateBuild {

    /**
     * 模板占位字符替换
     *
     * @param template    模板
     * @param reg 正则表达式(如："xx(.*?)yy"  =》替换模板中以xx开头yy结尾的所有占位字符)
     * @param t           占位符属性对象
     * @return 字符串
     */
    public static <T> String replace(String template, String reg, T t) {
        if (U.haveEmpty(template, t)) {
            return template;
        }

        List<Fields> replaceFields = getReplaceFields(template, reg);
        for (Fields fields : replaceFields) {
            String value = getValue(t, fields.getField());
            template = template.replace(fields.getFieldReg(),value);
        }
        return template;
    }





    /**
     * 根据正则获取模板中的占位符
     *
     * @param template 模板
     * @param rge      正则表达式(如："xx(.*?)yy"  =》获取模板中以xx开头yy结尾的所有占位符)
     * @return
     */
    public static List<Fields> getReplaceFields(String template, String rge) {
        Matcher matcher = Pattern.compile(rge).matcher(template);
        List<Fields> list = new ArrayList<>();
        while (matcher.find()) {
            list.add(new Fields(matcher.group(1),matcher.group()));
        }
        return list;
    }





    /**
     * 根据属性名称获取值
     *
     * @param t         对象
     * @param fieldName 属性名
     * @return 属性值
     */
    public static <T> String getValue(T t, String fieldName) {
        try {
            Class<?> aClass = t.getClass();
            if (t instanceof Map) {
                Map map = (Map) t;
                return map.get(fieldName) != null ? map.get(fieldName).toString() : "";
            }

            Field field = aClass.getDeclaredField(fieldName);
            field.setAccessible(true);
            return field.get(t) != null ? field.get(t).toString() : "";

        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }




    /**
     * @author zhangnx
     */
    @Data
    @AllArgsConstructor
     static class Fields {
        private String field;
        private String fieldReg;
    }
}
